<?php
/**
 * 字段验证器 以下为此类执行方法的说明
 *
 * @param data为需要验证的数据数组 键为验证方法 值为验证字段
 * @data = array(
 *           0 => ['name' => '用户名', 'value' => 'xiaofei', 'func' => 'is_empty']
 *           1 => [
 *              'name' => '密码', 
 *              'value' => 'xiaofei123', 
 *              'min' => 0, 
 *              'max' => 8,
 *              'func' => 'is_empty'
 *            ]
 *         )
 * @return ['res' => false, info =>'名称不能为空'] or ['res' => true]
 **/
namespace App\Common;
use Illuminate\Support\Str;
use App\Models\Admin\Grade;

class ValidateHandler
{
    public static function do($data)
    {
        foreach ($data as $v) {
            $func = Str::camel($v['func']);
            $result = self::$func($v);
            if (!$result['res']) {
                return $result;
            }
            continue;
        }

        return ['res' => true];
    }

    private static function isEmpty($data)
    {
        if (empty($data['value'])) return ['res' => false, 'info' => $data['name'].'不能为空'];

        return ['res' => true];
    }

    private static function lengthLimit($data)
    {
        if (mb_strlen($data['value']) == 0 )
            return ['res' => false, 'info' => $data['name'].'不能为空'];

        if (mb_strlen($data['value']) < $data['min'] )
            return ['res' => false, 'info' => $data['name'].'长度不能小于'.$data['min']];

        if (mb_strlen($data['value']) > $data['max'] )
            return ['res' => false, 'info' => $data['name'].'长度不能大于'.$data['max']];

        return ['res' => true];
    }

    private static function isPhone($data)
    {
        $pattern = "/^1(3[0-9]|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9]|1[1-9])\d{8}$/";
        $pregResult = preg_match($pattern, $data['value']);
        if (empty($pregResult)) {
            return ['res' => false, 'info' => '手机号不正确'];
        }
        return ['res' => true];
    }

    // 必需是数字或数字字符串 且 有数字范围限制 , 如果未设置 min max 默认只验证是否为数字
    private static function rangeNum($data)
    {
        if (!is_numeric($data['value']))
            return ['res' => false, 'info' => $data['name'].'必需是数字!'.$data['value']];

        if (isset($data['max']) && $data['value'] > $data['max']) 
            return ['res' => false, 'info' => $data['name'].'不能超过'.$data['min']];

        if (isset($data['min']) && $data['value'] < $data['min']) 
            return ['res' => false, 'info' => $data['name'].'不能小于'.$data['min']];

        return ['res' => true];
    }

    // 必需在指定数组范围中
    private static function rangeStatus($data)
    {
        if (!is_numeric($data['value']))
            return ['res' => false, 'info' => $data['name'].'必需是数字!'.$data['value']];

        if (!in_array($data['value'],$data['arr'])) {
            return ['res' => false, 'info' => $data['name'].'不是合法值'];
        }
        
        return ['res' => true];
    }

    // 商品录入时对于商品价格的验证
    private static function goodPrice($data)
    {
        $storeId = $data['store_id'];
        $price = (array)$data['value'];

        $grade = new Grade;
        // 判断价格是否有空
        foreach ($price as $k => $item) {
            if (empty($item)) {
                $grade = Grade::where('store_id', $storeId)->where('level', $k)->first();
                return ['res' => false, 'info' => "请录入".$grade->title."的".$data['name']];
            }
        }

        return ['res' => true];
    }

    // 判断是否全是中文 用于真实姓名判断
    private static function isAllChinese($data)
    {
        //新疆等少数民族可能有·
        if (strpos($data['value'], '·')) {
            //将·去掉，看看剩下的是不是都是中文
            $data['value'] = str_replace("·", '', $data['value']);
            if (preg_match('/^[\x7f-\xff]+$/', $data['value'])) {
                return ['res' => true];//全是中文
            } else {
                return ['res' => false, 'info' => $data['value'].'必须全是汉字'];//不全是中文
            }
        } else {
            if (preg_match('/^[\x7f-\xff]+$/', $data['value'])) {
                return ['res' => true];//全是中文
            } else {
                return ['res' => false, 'info' => $data['value'].'必须全是汉字'];//不全是中文
            }
        }
    }

    // 验证银行卡
    private static function verificationBankCard($data)
    {   
        $card_code = str_split(str_replace(' ','',$data['value']));
        $last_n = $card_code[count($card_code)-1];
        krsort($card_code);
        $i = 1;
        $total = 0;
        foreach ($card_code as $n){
            if(!is_numeric($n)){
                return false;
            }
            if($i%2==0){
                $ix = $n*2;
                if($ix>=10){
                    $nx = 1 + ($ix % 10);
                    $total += $nx;
                }else{
                    $total += $ix;
                }
            }else{
                $total += $n;
            }
            $i++;
        }
        $total -= $last_n;
        $x = ($total % 10) == 0 ? 0 : 10 - ($total % 10);
        if($x == $last_n || ($x == 0 && $total % 10 == 0)){
            return ['res' => true];
        }
        return ['res' => false, 'info' => '银行卡格式错误, 请检查'];
    }

    private static function isCard($data)
    {
        $id = $data['value'];
        $id = strtoupper($id);
        $regx = "/(^\d{15}$)|(^\d{17}([0-9]|X)$)/";
        $arr_split = array();
        if(!preg_match($regx, $id))
        {
            return ['res' => false, 'info' => '身份证格式错误, 请检查'];
        }
        if(15==strlen($id)) //检查15位
        {
            $regx = "/^(\d{6})+(\d{2})+(\d{2})+(\d{2})+(\d{3})$/";
    
            @preg_match($regx, $id, $arr_split);
            //检查生日日期是否正确
            $dtm_birth = "19".$arr_split[2] . '/' . $arr_split[3]. '/' .$arr_split[4];
            if(!strtotime($dtm_birth))
            {
                return ['res' => false, 'info' => '身份证格式错误, 请检查'];
            } else {
                return ['res' => true];
            }
        }
        else      //检查18位
        {
            $regx = "/^(\d{6})+(\d{4})+(\d{2})+(\d{2})+(\d{3})([0-9]|X)$/";
            @preg_match($regx, $id, $arr_split);
            $dtm_birth = $arr_split[2] . '/' . $arr_split[3]. '/' .$arr_split[4];
            if(!strtotime($dtm_birth)) //检查生日日期是否正确
            {
                return ['res' => false, 'info' => '身份证格式错误, 请检查'];
            }
            else
            {
                //检验18位身份证的校验码是否正确。
                //校验位按照ISO 7064:1983.MOD 11-2的规定生成，X可以认为是数字10。
                $arr_int = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
                $arr_ch = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
                $sign = 0;
                for ( $i = 0; $i < 17; $i++ )
                {
                    $b = (int) $id{$i};
                    $w = $arr_int[$i];
                    $sign += $b * $w;
                }
                $n = $sign % 11;
                $val_num = $arr_ch[$n];
                if ($val_num != substr($id,17, 1))
                {
                    return ['res' => false, 'info' => '身份证格式错误, 请检查'];
                } 
                else
                {
                    return ['res' => true];
                }
            }
        }
    
    }
}
